﻿namespace Legend.Caching
{
    using System;
    using System.Runtime.Caching;
    using System.Runtime.Serialization;

    /// <summary>
    /// A non persistent cach that stores it's items
    /// in the memory of the running process.
    /// </summary>
    public class ObjectCacheAdaptor
        : ICache
    {
        private readonly ObjectCache cache;
        
        public ObjectCacheAdaptor(ObjectCache cache)
        {
            this.cache = cache;
        }

        public ObjectCacheAdaptor()
            : this(new MemoryCache(Guid.NewGuid().ToString()))
        {
        }

        public void Insert(string key, object value, TimeSpan timeToLive)
        {
            if (timeToLive.Ticks < 1)
            {
                throw new ArgumentOutOfRangeException("timeToLive", "Can not cache with a negative expiration.");
            }

            if (value == null)
            {
                value = CacheNullValue.Value;
            }

            this.cache.Set(key, value, new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.Add(timeToLive) });
        }

        public bool TryGetValue(string key, out object value)
        {
            value = this.cache.Get(key);

            if (value is CacheNullValue)
            {
                value = null;
                return true;
            }

            return value != null;
        }

        public void Remove(string key)
        {
            this.cache.Remove(key);
        }

        private class CacheNullValue
        {
            private CacheNullValue()
            {
            }

            public static readonly CacheNullValue Value = new CacheNullValue();
        }
    }
}